package com.ds.list.arraylist;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyArrayList<T> implements Iterable<T> {

	private Object[]  items;
	private int cap;
	private int size;
	private final int INIT_SIZE = 16;
	
	public MyArrayList(){
		cap = INIT_SIZE;
		size = 0;
		items = new Object[cap];
	}
	
	public void add(T t) {
		
		add(size,t);
		
	}
	
	public void add(int pos,T t) {
		
		if(pos > size || pos < 0) {
			throw new IndexOutOfBoundsException(getMsg(pos));
		}
		if(size == cap) {
			incressment();
		}
		insert(t,pos);
		size++ ;
		
	}
	
	public T remove(int pos){
		
		if(pos >= size || pos < 0) {
			throw new IndexOutOfBoundsException(getMsg(pos));
		}
		Object temp = items[pos];
		for(int i = pos; i < size - 1 ; i++) {
			items[i] = items[i + 1];
		}
		items[size - 1] = null;
		size-- ;
		return (T)temp;
	}
	
	public boolean remove(T t) {
		
		int index = find(t);
		
		if(index < 0) {
			return false;
		}
		remove(index);
		return true;
		
	}
	
	public T get(int pos) {
		
		if(pos >= size || pos < 0) {
			throw new IndexOutOfBoundsException(getMsg(pos));
		}
		return (T)items[pos];
	}
	
	public int size() {
		
		return size;
		
	}
	
	@Override
	public String toString() {
		
		StringBuilder sb = new StringBuilder();
		sb.append("size : " + size);
		sb.append(" ,value : [");
		for(int i = 0 ; i < size ; i++) {
			sb.append(items[i]);
			if(i != size-1) {
				sb.append(",");
			}
		}
		sb.append("]");
		return sb.toString();
	}
	
	private void incressment() {
		
		cap = cap * 2 ;
		Object[] temp = items;
		items = new Object[cap];
		
		for(int i = 0;i < temp.length ; i++) {
			items[i] = temp[i];
		}
		temp = null;
	}
	
	private void insert(T t,int pos) {

		for(int i = size;i > pos; i--) {
			items[size] = items[size - 1];
		}
		items[pos] = t;
	}
	
	private int find(T t) {
		for(int i = 0; i < size; i++) {
			if(items[i].equals(t)) {
				return i;
			}
		}
		return -1;
		
	}
	
	private String getMsg(int pos) {
		
		return "size : " + size + "index : " + pos ;
		
	}
	
	@Override
	public Iterator<T> iterator() {
		// TODO Auto-generated method stub
		return new MyIterator();
	}
	
	private class MyIterator implements Iterator<T>{
		
		int cursor;
		int lastRet = -1;
		
		@Override
		public boolean hasNext() {
			// TODO Auto-generated method stub
			return cursor < size;
		}

		@Override
		public T next() {
			// TODO Auto-generated method stub
			int i = cursor;
			if(cursor >= size ) {
				throw new NoSuchElementException();
			}
			cursor++ ;
			return MyArrayList.this.get(lastRet = i);
		}
		
		public void remove() {
			
			if (lastRet < 0) {
                throw new IllegalStateException();
			}
			MyArrayList.this.remove(lastRet);
			cursor = lastRet;
			lastRet = -1;
			
		}
		
		
		
	}
	
	
}
